import json
import datetime
from model.model import Devops
from common.devops_common.heartbeat import ICMP, TCP, Http
from common.devops_common.metric import MetricMap
from package.fastapi.job import scheduler_job
from package.connector.kafka_db import kafka_producer


class DevopsView(Devops):

    HeartbeatPrefix = 'devops:heartbeat:cron:'
    HeartbeatTopic = 'devops_heartbeat'

    MetribeatcPrefix = 'devops:metricbeat:cron:'
    MetribeatcTopic = 'devops_metricbeat_{category}'

    @classmethod
    def execute_heartbeat(cls, id, host, port, configure):
        cls_ = cls.heartbeat_map(port, configure)
        now = int(datetime.datetime.utcnow().timestamp() * 1000)
        resp = cls_.heartbeat(host=host, port=port, **configure)
        cost = int(datetime.datetime.utcnow().timestamp() * 1000) - now
        
        if not id:
            return resp
        kafka_producer.send(cls.HeartbeatTopic, 
                            json.dumps({'id': id, 'host': host, 'port': port, '_time': now, 'cost': cost, **resp}, 
                                       ensure_ascii=False))

    @classmethod
    def execute_metricbeat(cls, id, category, host, port, configure):
        now = int(datetime.datetime.utcnow().timestamp() * 1000)
        cls_ = MetricMap[category]
        instance = cls_.init(**configure)
        resp = instance.metric()
        kafka_producer.send(cls.MetribeatcTopic.format(category), 
                            json.dumps({'id': id, 'host': host, 'port': port, '_time': now, **resp}, 
                                       ensure_ascii=False))


    @classmethod
    def heartbeat_map(cls, category, port):
        if category in ('apiserver',):
            return Http
        if category in ('mysql', 'oracle', 'postgres'):
            pass
        if category in ():
            pass
        if port:
            return TCP
        return ICMP

    @classmethod
    def add_job(cls, item):
        scheduler_job.add_job(job_id=f'{cls.HeartbeatPrefix}{item.id}',
                              func=cls.execute_heartbeat,
                              kwargs={'id': item.id, 'category': item.category, 'host': item.host, 'port': item.port, 
                                      'configure': item.heartbeat_configure.get('configure', {})},
                              cron=item.heartbeat_configure.get('cron')
                              )

        scheduler_job.add_job(job_id=f'{cls.MetribeatcPrefix}{item.id}',
                        func=cls.execute_metricbeat,
                        kwargs={'id': item.id, 'category': item.category, 'host': item.host, 'port': item.port, 
                                'configure': item.metricbeat_configure.get('configure', {})},
                        cron=item.metricbeat_configure.get('cron')
                        )

    @classmethod
    def delete_job(cls, item):
        scheduler_job.delete_job(job_id=f'{cls.HeartbeatPrefix}{item.id}')
        scheduler_job.delete_job(job_id=f'{cls.MetribeatcPrefix}{item.id}')

    @classmethod
    def create_devops(cls, session, body):
        item = cls.create_item(session, body, commit=False)
        cls.add_job(item)
        session.commit()
        return item

    @classmethod
    def update_devops(cls, session, filter_, update):
        item = cls.update_item(session=session, filter_=filter_, update=update)
        cls.add_job(item)
        return item

    @classmethod
    def delete_devopses(cls, session, filter_):
        items = cls.get_items(session=session, filter_=filter_)
        for item in items:
            cls.delete_job(item)
        return cls.delete_items(session=session, filter_=filter_)

    @classmethod
    def load_cron_job(cls, session):
        """加载定时任务"""
        for item in cls.get_items(session=session):
            cls.add_job(item)
